#ifndef HASH_H
#define HASH_H

#include <stdbool.h>
#include <stddef.h>

/* ******************************************************************
 *                DEFINICION DE LOS TIPOS DE DATOS
 * *****************************************************************/

typedef struct _datos datos_t;
typedef struct _claves claves_t;
typedef struct hash hash_t;
typedef struct hash_iter hash_iter_t;
typedef void (*hash_destruir_dato_t)(void *);


/* ******************************************************************
 *                    PRIMITIVAS DEL HASH
 * *****************************************************************/
// Crea un hash.
// Post: devuelve un nuevo hash vacío. 
hash_t *hash_crear(hash_destruir_dato_t destruir_dato);

// Guarda el par clave-dato en el hash.
// Pre: El hash fue creado.
bool hash_guardar(hash_t *hash, const char *clave, void *dato);

// Borra la clave y devuelve su valor.
// Pre: El hash fue creado y contiene esa clave, caso contrario devuelve NULL.
void *hash_borrar(hash_t *hash, const char *clave);

// Obtiene el valor de la clave.
// Pre: El hash fue creado y contiene esa clave, caso contrario devuelve NULL.
void *hash_obtener(const hash_t *hash, const char *clave);

// Devuelve true si la clave esta en el hash.
// re: El hash fue creado y contiene esa clave, caso contrario devuelve false.
bool hash_pertenece(const hash_t *hash, const char *clave);

// Devuelve la cantidad de elementos que contiene el hash.
// Pre: El hash fue creado.
size_t hash_cantidad(const hash_t *hash);

// Destruye el hash.
// Pre: El hash fue creado.
void hash_destruir(hash_t *hash);

/* ******************************************************************
 *                    PRIMITIVAS DEl ITERADOR
 * *****************************************************************/

// Crea el iterador del hash en la primer posicion del hash.
// Pre: El hash fue creado.
hash_iter_t *hash_iter_crear(const hash_t *hash);

// Avanza a la siguiente posicion en el hash.
// Pre: El hash y el iterador fueron creados.
bool hash_iter_avanzar(hash_iter_t *iter);

// Obtiene la clave de lo que esta apuntando el iterador
// Pre: El hash y el iterador fueron creados y tiene un elemento minimo. Caso contrario devuelve NULL.
const char *hash_iter_ver_actual(const hash_iter_t *iter);

// Devuelve true si el iterador esta en la ultima posicion del hash.
// Pre: El hash y el iterador fueron creados.
bool hash_iter_al_final(const hash_iter_t *iter);

// Destruye el iterador.
// Pre: El hash y el iterador fueron creados.
void hash_iter_destruir(hash_iter_t* iter);

#endif // HASH_H
